from conf.neo4j_cnx import NeoCnxPool

neo_cnx = NeoCnxPool()


class UserRole:

    def create_user(self, username, password, role_name):
        with neo_cnx.get_session() as session:
            query = (
                'MERGE (n:User {username: $username}) '
            )
            session.run(query, username=username)
            query = (
                'MATCH (n:User {username: $username}) '
                'SET n.password=$password'
            )
            session.run(query, username=username, password=password)
            self.create_role(role_name)
            self.update_user_role(username, role_name)

    @staticmethod
    def query_user_info(username):
        with neo_cnx.get_session() as session:
            query = (
                'MATCH (n:User {username: $username}) '
                'MATCH (n)-[:HasRole]->(role) '
                'RETURN n.password AS password, role.role_name AS role_name'
            )
            results = session.run(query, username=username)
            for record in results:
                return {'role_name': record['role_name'],
                        'password': record['password']}
            return None

    @staticmethod
    def create_role(role_name):
        with neo_cnx.get_session() as session:
            query = (
                'MERGE (n:Role {role_name: $role_name}) '
            )
            session.run(query, role_name=role_name)

    @staticmethod
    def update_user_role(username, role_name):
        with neo_cnx.get_session() as session:
            query = (
                'MATCH (u:User {username: $username}) '
                'MATCH (r:Role {role_name: $role_name}) '
                'MERGE (u)-[:HasRole]->(r)'
            )
            session.run(query, username=username, role_name=role_name)

    @staticmethod
    def del_user_role(username, role_name):
        with neo_cnx.get_session() as session:
            query = (
                'MATCH (u:User {username: $username}) '
                'MATCH (r:Role {role_name: $role_name}) '
                'MATCH (u)-[rel:HasRole]->(r) '
                'DELETE rel'
            )
            session.run(query, username=username, role_name=role_name)

    @staticmethod
    def query_user_role(username, password):
        with neo_cnx.get_session() as session:
            query = (
                'MATCH (u:User {username: $username, password: $password}) '
                'MATCH (u)-[:HasRole]->(r:Role) '
                'RETURN r.role_name AS role_name'
            )
            results = session.run(query, username=username, password=password)
            results = [record['role_name'] for record in results.data()]

            return results

    @staticmethod
    def query_all_roles():
        with neo_cnx.get_session() as session:
            query = (
                'MATCH (r:Role) '
                'RETURN r.role_name AS role_name'
            )
            results = session.run(query)
            results = [record['role_name'] for record in results.data()]
            return results


if __name__ == '__main__':
    user_role_app = UserRole()

    user_role_app.create_user(username='user', password='user2021', role_name='小萌新')
    user_role_app.create_user(username='editor', password='editor2021', role_name='编辑员')
    user_role_app.create_user(username='super', password='super2021', role_name='审查员')
    user_role_app.create_user(username='admin', password='admin2021', role_name='管理员')
    user_role_app.query_user_role(username='admin', password='admin2021')
